/**********************************************************************************
**
** Copyright (C) 2009 Jostein Bratlie
** Contact: jostein.bratlie@gmail.com | http://bratlie.info | http://episteme.hin.no
**
** This file is part of GMQtExt, a GMlib and Qt extension library
**
** GMQtExt is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** GMQtExt is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with GMQtExt.  If not, see <http://www.gnu.org/licenses/>.
**
**********************************************************************************/

#include <gmOpenGL>

#ifdef _WIN32
#include <QtOpenGL>
  #include <gmOpenGL>
#else
#include <QtCore>
//  #include <gmOpenGL>
  #ifdef GM_GL_EXTENSION
    #ifndef GL_GLEXT_PROTOTYPES
      #define GL_GLEXT_PROTOTYPES
    #endif
  #endif
  #include <QtOpenGL>
#endif


// Qt
#include <QtGui>

// GMlib
#include <gmCore>
#include <gmLightG>
#include <gmParametrics>

// Header
#include "graphicsscene.h"

namespace GMQtExt {

  GraphicsScene::GraphicsScene( QObject* parent, bool run_init ) : QGraphicsScene( parent ) {

    GMWindow::init();

    if( run_init )
      this->init();

    toggleRun();
  }


  void GraphicsScene::drawBackground( QPainter* painter, const QRectF& /*rect*/ ) {

    if( painter->paintEngine()->type() != QPaintEngine::OpenGL2 ) {
      qWarning(
        "OpenGLScene: drawBackground needs a "
        "QGLWidget to be set as viewport on the "
        "graphics view"
      );

      return;
    }

    glPushAttrib( GL_ALL_ATTRIB_BITS );
    {
      glMatrixMode( GL_PROJECTION );
      glPushMatrix();
      {
        glMatrixMode( GL_MODELVIEW );
        glPushMatrix();
        {

          glDisable( GL_BLEND );

          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
          glShadeModel(GL_SMOOTH);
          glEnable(GL_DEPTH_TEST);
          glEnable(GL_LIGHTING);

          for( int i = 0; i < _lights.getSize(); i++ )
            _lights[i]->enable();

          // Run display routines
          display();

        }
        glMatrixMode( GL_MODELVIEW );
        glPopMatrix();
      }
      glMatrixMode( GL_PROJECTION );
      glPopMatrix();

    }
    glPopAttrib();

    glEnable( GL_BLEND );

    QTimer::singleShot(20, this, SLOT(update()));
  }


  QWidget* GraphicsScene::getNewDialog( const QString& window_title, double opacity ) const {

    QDialog *dialog = new QDialog( 0, Qt::CustomizeWindowHint | Qt::WindowTitleHint );
    dialog->setWindowOpacity( opacity );
    dialog->setWindowTitle( window_title );
    dialog->setLayout( new QVBoxLayout );

    return dialog;
  }


  QWidget* GraphicsScene::getNewWidget( double opacity ) const {

    QWidget *widget = new QWidget();
    widget->setWindowOpacity( opacity );
    widget->setLayout( new QVBoxLayout );

    return widget;
  }


  void GraphicsScene::init() {

    using namespace GMlib;

    // Insert a light
    Point3D<GLfloat> init_light_pos( 2.0, 4.0, 10 );
    insertLight( new PointLightG( GMlib::GMcolor::White, GMlib::GMcolor::White, GMlib::GMcolor::White, init_light_pos ), false );

    // Insert Sun
    insertSun();

    // Camera
    Point3D<float> init_cam_pos(  0.0f, 0.0f, 0.0f );
    Vector3D<float> init_cam_dir( 0.0f, 1.0f, 0.0f );
    Vector3D<float> init_cam_up(  0.0f, 0.0f, 1.0f );

    Camera *cam = new Camera( init_cam_pos, init_cam_dir, init_cam_up );
    cam->setScene( this );
    cam->setCuttingPlanes( 1, 8000 );
    cam->setFrustumVisible( false );
    cam->enableCulling( true );
    cam->rotateGlobal( Angle(-45), Vector3D<float>( 1.0f, 0.0f, 0.0f ) );
    cam->translate( Vector3D<float>( 0.0f, -120.0f, 120.0f ) );

    insertCamera( cam );

    setViewSet( _cameras.index( cam ) );

  }


  void GraphicsScene::resize( const QRectF& rect ) {

    setSceneRect( rect );
    reshape( rect.size().width(), rect.size().height() );
  }

} // END namespace GMQtExt


